﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ferreteria.Clases;

namespace Ferreteria.Forms
{
    public partial class frmEmitirFactura : Form
    {
        DisancoEntities context;
        int pedId;
        DataTable dtLineas;
        decimal subtotal;
        decimal iva;
        int autorizacionId;
        int numeroFacturaInicial;
        int numeroFacturaFinal;
        int cantFacturas;
        int cantlineasxfactura;
        int k;
        int NroFactura;
        Ventas VentaImprimir;
        int cantFactRestantes;
        bool PrimerFactura;
        decimal totalfactanterior = 0;
        decimal totfact = 0;
        decimal totalacumulado = 0;
        decimal descuento;
        decimal subtotal_descontado;

        private Font printFont = new Font("Arial", 10);

        public frmEmitirFactura(int ped_id)
        {
            InitializeComponent();
            pedId = ped_id;

            context = new DisancoEntities();

            var pedido = context.Pedido.FirstOrDefault(p => p.ped_id == ped_id);
            var cliente = pedido.Clientes;
            
            int nroLineas = pedido.LineaPedido.Count;
            int maxLineas = Clases.Constantes.maximoLineasFactura;

            //Calculo de la cant de facturas necesarias
            cantFacturas = 1;
            while (nroLineas > maxLineas)
            {
                cantFacturas += 1;
                nroLineas -= maxLineas;
            }

            //Obtener las condiciones de iva disponibles
            cmbTipo.DataSource = Funcion.obtenerTiposFactura(pedido.Clientes.CondicionIVA.condicion_sigla);

            bool autorizado = buscarAutorizaciones(cmbTipo.SelectedItem.ToString());

            if (autorizado)
            {
                //Cargar datos del cliente
                txtbCliNombre.Text = pedido.Clientes.cliente_nombre;
                txtbCliLocalidad.Text = pedido.Clientes.cliente_localidad;
                txtbCliDireccion.Text = pedido.Clientes.cliente_direccion;
                txtbCliCondiva.Text = pedido.Clientes.CondicionIVA.condicion_sigla;
                txtbCliCuit.Text = pedido.Clientes.cliente_cuit;

                cargarLineasPedido();

                calcularTotales();
            }
            else
            {
                MessageBox.Show("No se encontraron autorizaciones validas activas");
               
            }
        }

        void calcularTotales()
        {            
            descuento = numDescuento.Value / 100;
            subtotal_descontado = subtotal / (1 + descuento);
            iva = subtotal_descontado * Constantes.IVA;

            txbIva.Text = iva.ToString("0.00");
            txbSubTotDesc.Text = subtotal_descontado.ToString("0.00");

            string tipo = cmbTipo.SelectedItem.ToString();
            switch (tipo)
            {
                case "A":
                    {
                        txbTotal.Text = (subtotal_descontado + iva).ToString("0.00");
                        txbIva.Enabled = true;
                        break;
                    }
                case "X":
                    {
                        txbTotal.Text = (subtotal_descontado).ToString("0.00");
                        txbSubTotal.Enabled = false;
                        txbIva.Enabled = false;
                        break;
                    }
                case "B":
                    {
                        txbTotal.Text = (subtotal_descontado).ToString("0.00");
                        txbSubTotal.Enabled = false;
                        txbIva.Enabled = false;
                        txbIva.Text = " ";
                        txbSubTotal.Text = " ";
                        break;
                    }
                default:
                    {
                        txbTotal.Text = (subtotal_descontado + iva).ToString("0.00");
                        txbIva.Enabled = true;
                        break;
                    }
            }
        }

        void cargarLineasPedido()
        {
            context = new DisancoEntities();
            decimal preciounitfila;
            decimal preciototfila;
            dtLineas = new DataTable();
            dtLineas.Columns.Add("id");
            dtLineas.Columns.Add("Articulo");
            dtLineas.Columns.Add("Cantidad");
            dtLineas.Columns.Add("Precio Unitario");
            dtLineas.Columns.Add("Precio Total");

            subtotal = 0;
            var pedido = context.Pedido.FirstOrDefault(p => p.ped_id == pedId);
            
            foreach (var linea in pedido.LineaPedido)
            {
                preciounitfila = 0;
                DataRow fila = dtLineas.NewRow();
                fila["id"] = linea.linped_id;
                fila["Articulo"] = linea.Articulos.art_nombre;
                fila["Cantidad"] = linea.ped_cant;

                if ((string)cmbTipo.SelectedItem == "B")
                {
                    preciounitfila = linea.ped_precio + linea.ped_precio * Constantes.IVA;
                    fila["Precio Unitario"] = "$ " + preciounitfila;
                }
                else
                {
                    fila["Precio Unitario"] = "$ " + linea.ped_precio;
                    preciounitfila = linea.ped_precio;
                }
                fila["Precio Total"] = "$ " + preciounitfila * linea.ped_cant;
                preciototfila = preciounitfila * linea.ped_cant;
                dtLineas.Rows.Add(fila);

                subtotal += preciototfila;
            }

            subtotal = Math.Round(subtotal, 2);

            txbSubTotal.Text = subtotal.ToString("0.00");

            dgvListaArt.DataSource = dtLineas;
            dgvListaArt.Columns["id"].Visible = false;
            dgvListaArt.Columns["Articulo"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dgvListaArt.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dgvListaArt.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
        }

        private bool buscarAutorizaciones(string tipo)
        {
            //Se busca una autorizacion valida, y se generan los
            //numeros de factura inicial y final, controlando que
            //el final no exceda el limite de la autorizacion

            //numeroFacturaInicial = 0;
            context = new DisancoEntities();
            bool autorizado = false;

            foreach (var auth in context.Autorizaciones)
            {
                if (auth.autorizacion_tipo_comp == tipo)
                {
                    if (auth.autorizacion_estado)
                    {
                        if (auth.autorizacion_limite_fecha.Date > DateTime.Now.Date)
                        {
                            autorizacionId = auth.autorizacion_id;
                            numeroFacturaInicial = auth.autorizacion_ultimo_numero + 1;
                            numeroFacturaFinal = numeroFacturaInicial + cantFacturas - 1;

                            if (numeroFacturaFinal > auth.autorizacion_limite_max)
                            {
                                MessageBox.Show("Se exedio el limite de Nros de Factura");
                            }
                            else
                            {
                                autorizado = true;
                            }
                            break;
                        }
                    }
                }
            }

            if (autorizado)
            {
                string inicio = numeroFacturaInicial.ToString("000000000000");
                string fin = numeroFacturaFinal.ToString("000000000000");

                txbNroFactIni1.Text = inicio.Substring(0, 4);
                txbNroFactIni2.Text = inicio.Substring(4);
                txbNroFactFin1.Text = fin.Substring(0, 4);
                txbNroFactFin2.Text = fin.Substring(4);
            }
           
            return autorizado;
        }

        private void cmbTipo_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool autorizado = buscarAutorizaciones(cmbTipo.SelectedItem.ToString());
            if (autorizado)
            {
                cargarLineasPedido();
                calcularTotales();
            }
            else
            {
                MessageBox.Show("No se encontraron autorizaciones validas activas");
            }
        }

        private void btnEmitir_Click(object sender, EventArgs e)
        {
            //try
            //{
                context = new DisancoEntities();
                var pedido = context.Pedido.FirstOrDefault(p => p.ped_id == pedId);

                bool valido = true;
                string lista = "Stock insuficiente para los siguientes articulos:\n";

                //Verificar existencia de stock
                foreach (var linea in pedido.LineaPedido)
                {
                    if (linea.ped_cant > linea.Articulos.art_stock)
                    {
                        valido = false;
                        lista += linea.Articulos.art_nombre + " (" + linea.Articulos.art_stock.ToString() + ")\n";
                    }
                }

                if (valido)
                {
                    //Actualizar stock de cada articulo
                    foreach (var linea in pedido.LineaPedido)
                    {
                        linea.Articulos.art_stock -= linea.ped_cant;
                    }

                    //Registrar ultimo numero de factura usado
                    var auth = context.Autorizaciones.FirstOrDefault(a => a.autorizacion_id == autorizacionId);
                    auth.autorizacion_ultimo_numero = numeroFacturaFinal;

                    //Registrar la nueva factura
                    Ventas nuevaVenta = new Ventas();
                    nuevaVenta.cliente_id = pedido.cliente_id;
                    nuevaVenta.venta_fecha = DateTime.Now;
                    nuevaVenta.venta_descuento = descuento;
                    nuevaVenta.venta_estado = Estado.Emitida;
                    nuevaVenta.venta_tipo_comprobante = cmbTipo.SelectedItem.ToString();
                    nuevaVenta.venta_nro_inicio = numeroFacturaInicial;
                    nuevaVenta.venta_nro_fin = numeroFacturaFinal;
                    nuevaVenta.venta_subtotal = subtotal;
                    nuevaVenta.venta_iva = iva;

                    foreach (var lineaPedido in pedido.LineaPedido)
                    {
                        LineaVenta nuevaLineaVenta = new LineaVenta();
                        nuevaLineaVenta.art_id = lineaPedido.art_id;
                        nuevaLineaVenta.cantidad_venta = lineaPedido.ped_cant;
                        nuevaLineaVenta.precio_venta = lineaPedido.ped_precio;

                        nuevaVenta.LineaVenta.Add(nuevaLineaVenta);
                    }

                    //Registro una nueva cuenta para esta factura
                    Cuentas nuevaCuenta = new Cuentas();
                    nuevaCuenta.cuenta_fecha = DateTime.Now;
                    nuevaCuenta.cuenta_monto = subtotal_descontado + iva;
                    nuevaCuenta.cuenta_pagado = 0;
                    nuevaCuenta.cliente_id = pedido.cliente_id;

                    nuevaVenta.Cuentas.Add(nuevaCuenta);

                    pedido.ped_estado = Estado.Emitida;

                    context.Ventas.AddObject(nuevaVenta);
                    context.SaveChanges();
                    VentaImprimir = new Ventas();
                    VentaImprimir = nuevaVenta;

                    MessageBox.Show("Factura guardada con exito", "Operación Exitosa", MessageBoxButtons.OK, MessageBoxIcon.Information);
                  
                    this.Close();
                    imprimir();
                }
                else
                {
                    MessageBox.Show(lista);
                }
            //}
            //catch (Exception err)
            //{
            //    MessageBox.Show(err.Message);
            //}
        }

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        void imprimir()
        {
          
          NroFactura = numeroFacturaInicial;
          
          //totalacumulado = 0;
          //totalfactanterior = 0;
          //cantFactRestantes = cantFacturas;

          //if (cantFacturas > 1)// Si hay q imprimir varias Facturas
          //  {
          //      printDialog.Document = pdVariasFacturaA;
          //      DialogResult resultado = printDialog.ShowDialog();
            
          //      if (resultado == DialogResult.OK)
          //      {
          //          pdVariasFacturaA.PrinterSettings = printDialog.PrinterSettings;
          //          PrimerFactura = true;
          //          int lnfactura = dtLineas.Rows.Count;
          //          cantlineasxfactura = Clases.Constantes.maximoLineasFactura - 1;
          //          k = 0;

          //          printPreviewDialog.Document = pdVariasFacturaA;
          //          ((Form)printPreviewDialog).WindowState = FormWindowState.Maximized;  

          //          for (int j = 1; j <= cantFacturas; j++) 
          //          {
                        
          //              MessageBox.Show("Imprimir Factura " + j + " de " + cantFacturas);
          //              totfact = 0;
          //              printPreviewDialog.ShowDialog();
                        
          //              NroFactura = NroFactura + 1;
          //              totalfactanterior = totalacumulado;
          //              PrimerFactura = false;
          //              cantFactRestantes = cantFactRestantes - 1;
          //              k = k + Clases.Constantes.maximoLineasFactura;

          //              if (cantFactRestantes == 1)
          //              {
          //                  int lnrestantes = lnfactura - cantlineasxfactura - 1;
          //                  cantlineasxfactura = cantlineasxfactura + lnrestantes;
          //              }
          //              else
          //                  if (cantFactRestantes > 1)
          //                  {
          //                      cantlineasxfactura = cantlineasxfactura + Clases.Constantes.maximoLineasFactura;
          //                  }
          //          }
          //      }
          //  }
          //else
          //{
              printDialog.Document = pdFacturaUnicaA;// Si hay q imprimir una Factura 
              DialogResult resultadounico = printDialog.ShowDialog();

              if (resultadounico == DialogResult.OK)
              {
                  pdFacturaUnicaA.PrinterSettings = printDialog.PrinterSettings;
                  printPreviewDialog.Document = pdFacturaUnicaA;
                  ((Form)printPreviewDialog).WindowState = FormWindowState.Maximized;
                  printPreviewDialog.ShowDialog();
              }
          //}   
        }     
             
        private void pdFacturaUnicaA_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            // imprimir una factura 
            context = new DisancoEntities();
           
            int margenX = 50;
            int margenY = 50;
            int anchoHoja = 800;

            PointF punto = new PointF();
            punto.X = anchoHoja / 2;
            punto.Y = margenY + 30;

            StringFormat formato = new StringFormat();
            formato.Alignment = StringAlignment.Center;

            string factnumero = NroFactura.ToString("0000-00000000");
            string fecha = VentaImprimir.venta_fecha.Date.ToString("dd/MM/yyyy");
            e.Graphics.DrawString(factnumero, printFont, Brushes.Black, 550, 40);

            e.Graphics.DrawString(fecha, printFont, Brushes.Black, 550, 70);
            e.Graphics.DrawLine(Pens.Black, 10, 120, 800, 120);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_nombre,printFont, Brushes.Black, 130, 130);
            
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_direccion, printFont, Brushes.Black, 130, 150);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_localidad, printFont, Brushes.Black, 550, 150);
            e.Graphics.DrawString(VentaImprimir.Clientes.CondicionIVA.condicion_sigla, printFont, Brushes.Black, 130, 170);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_cuit, printFont, Brushes.Black, 550, 170);
            e.Graphics.DrawLine(Pens.Black, 10, 200, 800, 200);

            String Cant = "Cantidad";
            e.Graphics.DrawString(Cant, printFont, Brushes.Black, 82, 210);
            String Cod = "Codigo Art.";
            e.Graphics.DrawString(Cod, printFont, Brushes.Black, 180, 210);
            String Art = "Articulo";
            e.Graphics.DrawString(Art, printFont, Brushes.Black, 400, 210);
            
            String PrecioU = "Precio U";
            e.Graphics.DrawString(PrecioU, printFont, Brushes.Black, 600, 210);
            String Importe = "Importe";
            e.Graphics.DrawString(Importe, printFont, Brushes.Black, 700, 210);


            //dibujado de las lineas de factura
            int posY = 230;
            int anchoLinea = 25;
            int posCantidad = margenX + 55;
            int posArticulo = posCantidad + 175;

            int posPrecioU = posArticulo + 328;
            int posPrecioT = posPrecioU + 100;
           

            foreach (DataRow fila in dtLineas.Rows)
            {
                e.Graphics.DrawString(fila["Cantidad"].ToString(), printFont, Brushes.Black, posCantidad, posY);
                e.Graphics.DrawString(fila["Articulo"].ToString(), printFont, Brushes.Black, posArticulo, posY);
             
                e.Graphics.DrawString(fila["Precio Unitario"].ToString(), printFont, Brushes.Black, posPrecioU, posY);
                e.Graphics.DrawString(fila["Precio Total"].ToString(), printFont, Brushes.Black, posPrecioT, posY);
                
                posY += anchoLinea;
            }

            int lineafin = 1000;
            int posSubtotX = 80;
            if ((string)cmbTipo.SelectedItem == "A")
            {
                String subtot = "SUB-TOTAL  $";
                e.Graphics.DrawString(subtot, printFont, Brushes.Black, posSubtotX, lineafin);
                e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_subtotal), printFont, Brushes.Black, posSubtotX + 100, lineafin);

                String iva = "IVA  $";
                e.Graphics.DrawString(iva, printFont, Brushes.Black, posSubtotX + 180, lineafin);
                e.Graphics.DrawString(VentaImprimir.venta_iva.ToString("0.00"), printFont, Brushes.Black, posSubtotX + 220, lineafin);

                String desc = "Descuento  $";
                e.Graphics.DrawString(desc, printFont, Brushes.Black, posSubtotX + 350, lineafin);
                e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_descuento), printFont, Brushes.Black, posSubtotX + 435, lineafin);

                String tot = "TOTAL  $";
                e.Graphics.DrawString(tot, printFont, Brushes.Black, posSubtotX + 570, lineafin);
                decimal total = Decimal.Round(Convert.ToDecimal(VentaImprimir.venta_monto), 2);
                e.Graphics.DrawString(Convert.ToString(total), printFont, Brushes.Black, posSubtotX + 645, lineafin);
            }
            else {// Si es B la Factura
                String tot = "TOTAL  $";
                e.Graphics.DrawString(tot, printFont, Brushes.Black, posSubtotX + 570, lineafin);
                decimal totalB = Decimal.Round(Convert.ToDecimal(VentaImprimir.venta_monto), 2);
                e.Graphics.DrawString(Convert.ToString(totalB), printFont, Brushes.Black, posSubtotX + 645, lineafin);
                 }


        }

        private void pdVariasFacturaA_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //Imprimir varias facturas A
            context = new DisancoEntities();

            int margenX = 50;
            int margenY = 50;
            int anchoHoja = 800;

            PointF punto = new PointF();
            punto.X = anchoHoja / 2;
            punto.Y = margenY + 30;

            StringFormat formato = new StringFormat();
            formato.Alignment = StringAlignment.Center;

            string factnumero = NroFactura.ToString("0000-00000000");
            string fecha = VentaImprimir.venta_fecha.Date.ToString("dd/MM/yyyy");
            e.Graphics.DrawString(factnumero, printFont, Brushes.Black, 550, 40);

            e.Graphics.DrawString(fecha, printFont, Brushes.Black, 550, 70);
            e.Graphics.DrawLine(Pens.Black, 10, 120, 800, 120);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_nombre, printFont, Brushes.Black, 130, 130);

            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_direccion, printFont, Brushes.Black, 130, 150);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_localidad, printFont, Brushes.Black, 550, 150);
            e.Graphics.DrawString(VentaImprimir.Clientes.CondicionIVA.condicion_sigla, printFont, Brushes.Black, 130, 170);
            e.Graphics.DrawString(VentaImprimir.Clientes.cliente_cuit, printFont, Brushes.Black, 550, 170);
            e.Graphics.DrawLine(Pens.Black, 10, 200, 800, 200);

            String Cod = "Codigo Art.";
            e.Graphics.DrawString(Cod, printFont, Brushes.Black, 80, 210);
            String Art = "Articulo";
            e.Graphics.DrawString(Art, printFont, Brushes.Black, 300, 210);
            String Cant = "Cantidad";
            e.Graphics.DrawString(Cant, printFont, Brushes.Black, 480, 210);
            String PrecioU = "Precio U";
            e.Graphics.DrawString(PrecioU, printFont, Brushes.Black, 600, 210);
            String Importe = "Importe";
            e.Graphics.DrawString(Importe, printFont, Brushes.Black, 700, 210);


            //Proceso de dibujado de las lineas de factura
            int posY = 250;
            int anchoLinea = 25;
            int posArticulo = margenX + 140;
            int posCantidad = posArticulo + 320;
            int posPrecioU = posCantidad + 100;
            int posPrecioT = posPrecioU + 100;

            

            for (int j = k; j <= cantlineasxfactura; j++)
            {
                DataRow filafact = dtLineas.Rows[j];
                   
                e.Graphics.DrawString(filafact["Articulo"].ToString(), printFont, Brushes.Black, posArticulo, posY);
                e.Graphics.DrawString(filafact["Cantidad"].ToString(), printFont, Brushes.Black, posCantidad, posY);
                e.Graphics.DrawString(filafact["Precio Unitario"].ToString(), printFont, Brushes.Black, posPrecioU, posY);
                e.Graphics.DrawString(filafact["Precio Total"].ToString(), printFont, Brushes.Black, posPrecioT, posY);
                decimal totalfila = Convert.ToDecimal(filafact["Precio Total"].ToString().Replace("$ ", "")); 
             
                totfact = totfact + totalfila;
                posY += anchoLinea;
            }

            int lineafin = 1000;
            int posSubtotX = 80;
            totalacumulado = totalacumulado + totfact;
            
            if (cantFactRestantes == 1)
            {
                if ((string)cmbTipo.SelectedItem == "A")
                {
                    String subtot = "SUB-TOTAL  $";
                    e.Graphics.DrawString(subtot, printFont, Brushes.Black, posSubtotX, lineafin);
                    e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_subtotal), printFont, Brushes.Black, posSubtotX + 100, lineafin);

                    String iva = "IVA  $";
                    e.Graphics.DrawString(iva, printFont, Brushes.Black, posSubtotX + 220, lineafin);
                    e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_iva), printFont, Brushes.Black, posSubtotX + 260, lineafin);

                    String desc = "Descuento  $";
                    e.Graphics.DrawString(desc, printFont, Brushes.Black, posSubtotX + 370, lineafin);
                    e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_descuento), printFont, Brushes.Black, posSubtotX + 455, lineafin);

                    String tot = "TOTAL  $";
                    e.Graphics.DrawString(tot, printFont, Brushes.Black, posSubtotX + 570, lineafin);
                    e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_monto), printFont, Brushes.Black, posSubtotX + 650, lineafin);
                }
                else 
                {
                    String tot = "TOTAL  $";
                    e.Graphics.DrawString(tot, printFont, Brushes.Black, posSubtotX + 570, lineafin);
                    e.Graphics.DrawString(Convert.ToString(VentaImprimir.venta_monto), printFont, Brushes.Black, posSubtotX + 650, lineafin);
                }
            }
            else
                {
                    String tpte = "Transporte ----------------------------------------------------------------------------  $";
                    e.Graphics.DrawString(tpte, printFont, Brushes.Black, posSubtotX, lineafin);
                    e.Graphics.DrawString(Convert.ToString(totalacumulado), printFont, Brushes.Black, posSubtotX + 650, lineafin);
                    
                }

            if (PrimerFactura == false)
               {
                String tpte = "Transporte ----------------------------------------------------------------------------------  $";
                e.Graphics.DrawString(tpte, printFont, Brushes.Black, posSubtotX, 230);
                e.Graphics.DrawString(Convert.ToString(totalfactanterior), printFont, Brushes.Black, posSubtotX + 650, 230);
               }
           
            context = null;
        }

        private void numDescuento_ValueChanged(object sender, EventArgs e)
        {
            descuento = numDescuento.Value / 100;

            calcularTotales();
        }
    }
}
